﻿using System;
using System.Collections;
using System.Collections.Generic;
using com.yoozoo.gta.Extension;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Video;
using Yoozoo.Mars.Got;
using Yoozoo.UI.YGUI;

public static class ComponentEx
{
    public static Component AddComponent(this Component component, System.Type componentType)
    {
        //UnityEngine.Debug.LogWarning($"@------Type:{componentType.Name} component:{component.getFullName()}");
        return component.gameObject.AddComponent(componentType);
    }
    public static Component GetOrAddComponent(this Component component, System.Type componentType)
    {
        Component comp = component.gameObject.GetComponent(componentType);
        if (comp == null)
        {
            comp = component.AddComponent(componentType);
        }

        return comp;
    }
    public static void SetActive(this Component component, bool value)
    {
        component.gameObject.SetActive(value);
    }
    public static void SetActive(this Component component, string relativePath, bool value)
    {
        component.transform.Find(relativePath).SetActive(value);
    }

    public static void SetText(this Component component, string value)
    {
        component.GetComponent<YText>().text = value;
    }
    public static void SetText(this Component component, string relativePath, string value)
    {
        component.transform.Find(relativePath).SetText(value);
    }

    public static void SetLayer(this Component component, int layer)
    {
        component.gameObject.SetLayerRecursively(layer);
    }
    public static void SetLayer(this Component component, string relativePath, int layer)
    {
        component.transform.Find(relativePath).SetLayer(layer);
    }



    /// <summary>
    /// 
    /// </summary>
    /// <param name="component"></param>
    /// <param name="toggleGroup"></param>
    public static void SetToggleGroup(this Component component, Component toggleGroup)
    {
        component.GetComponent<YToggle>().group = toggleGroup.GetComponent<YToggleGroup>();
    }



    public static void PlayVideoClip(this Component component, VideoClip videoClip, System.Action callback = default, Camera camera = default)
    {
        VideoPlayer player = component.GetComponent<VideoPlayer>();
        if (player == null)
            player = component.AddComponent<VideoPlayer>();
        
        if (camera == default)
            camera = component.GetComponentInParent<Camera>();

        player.source = VideoSource.VideoClip;
        player.renderMode = VideoRenderMode.CameraNearPlane;
        player.targetCamera = camera;
        player.targetCameraAlpha = 1.0f;
        
        player.clip  = videoClip;
        player.Play();
        
        IEnumerator EnumeratorListener()
        {
            while (true)
            {
                Debug.Log($"{player.clip} {player.isPlaying}  {player.isPaused}  {player.frame}/{player.frameCount}  {player.length}");
                
                //long totalFrame = (long) player.frameCount - 1;
                //if (totalFrame > 0 && player.frame >= totalFrame)
                //{
                //    break;
                //}
                //yield return null;

                if (player.Invalid())
                {
                    yield break;
                }
                if (player.length > 0)
                {
                    yield return new WaitForSeconds((float)player.length);
                    break;
                }

                yield return null;
            }


            float tweenTime = 0.5f;
            while (tweenTime > 0)
            {
                tweenTime -= Time.deltaTime;
                if (player.Valid())
                {
                    player.targetCameraAlpha = tweenTime * 2;
                }
                else
                {
                    yield break;
                }
                yield return null;
            }
            
            callback?.Invoke();
        }
        
        Timers.inst.StartCoroutine(EnumeratorListener());
    }
    public static void PlayVideoClipUrl(this Component component, string url, System.Action callback = default, Camera camera = default)
    {
        VideoPlayer player = component.GetComponent<VideoPlayer>();
        if (player == null)
            player = component.AddComponent<VideoPlayer>();
        
        if (camera == default)
            camera = component.GetComponentInParent<Camera>();

        player.source = VideoSource.Url;
        player.renderMode = VideoRenderMode.CameraNearPlane;
        player.targetCamera = camera;
        player.targetCameraAlpha = 1.0f;
        
        player.url  = url;
        player.Play();

        IEnumerator EnumeratorListener()
        {
            while (true)
            {
                //Debug.LogError($"{player.isPlaying}  {player.isPaused}  {player.frame}/{player.frameCount}  {player.length}");
                
                //long totalFrame = (long) player.frameCount - 1;
                //if (totalFrame > 0 && player.frame >= totalFrame)
                //{
                //    break;
                //}
                //yield return null;

                if (player.Invalid())
                {
                    yield break;
                }
                if (player.length > 0)
                {
                    yield return new WaitForSeconds((float)player.length);
                    break;
                }

                yield return null;
            }


            float tweenTime = 0.5f;
            while (tweenTime > 0)
            {
                tweenTime -= Time.deltaTime;
                if (player.Valid())
                {
                    player.targetCameraAlpha = tweenTime * 2;
                }
                else
                {
                    yield break;
                }
                yield return null;
            }
            
            callback?.Invoke();
        }
        
        Timers.inst.StartCoroutine(EnumeratorListener());
    }
    public static VideoPlayer VideoPlayer(this Component component)
    {
        var videoPlayer = component.GetComponent<VideoPlayer>();
        return videoPlayer;
    }
    public static YRawImage YRawImage(this Component component)
    {
        var rawImage = component.GetComponent<YRawImage>();
        return rawImage;
    }
    public static VideoWrapper VideoWrapper(this Component component)
    {
        return component.GetComponent<VideoWrapper>();
    }
    
    /// <summary>
    /// 内存优势
    /// 速度 2000
    /// 内存 0.7K
    /// </summary>
    /// <returns></returns>
    public static string getFullNameEx(this Component component, Transform transform)
    {
        try
        {
            List<string> paths = new List<string>();
            Transform current = transform;
            while (current != null)
            {
                paths.Add(current.name);
                current = current.parent;
            }
            //路径反转
            paths.Reverse();
            //返回全路径
            return string.Join("/", paths);
        }
        catch (Exception e)
        {
            return transform.name;
        }
    }
    /// <summary>
    /// 速度优势
    /// 速度 1000
    /// 内存 1.0k
    /// </summary>
    /// <param name="transform"></param>
    /// <returns></returns>
    public static string getFullName(this Component component, Transform transform = null)
    {
        if (transform == null)
            transform = component.transform;
        
        if (transform.parent == null)
        {
            return transform.name;
        }
        return $"{getFullName(component, transform.parent)}/{transform.name}";
    }
}
